package org.csu.mybigpro.service;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.csu.mybigpro.domain.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class LiveKitService {

    private final String apiKey;
    private final SecretKey apiSecret;

    public LiveKitService(
            @Value("${livekit.api.key}") String apiKey,
            @Value("${livekit.api.secret}") String apiSecretString) {
        this.apiKey = apiKey;
        this.apiSecret = Keys.hmacShaKeyFor(apiSecretString.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 根据角色为用户生成加入 LiveKit 房间的 Token
     */
    public String getJoinToken(String roomName, User user, String role) {
        final long TOKEN_VALIDITY_SECONDS = 6 * 60 * 60;

        Map<String, Object> videoGrant = new HashMap<>();
        videoGrant.put("room", roomName);
        videoGrant.put("roomJoin", true);
        videoGrant.put("canSubscribe", true);

        // --- 【核心修复】将音视频发布权限和数据发布权限分离 ---

        // 1. 只有 'publisher' (教师) 角色的用户才有权发布音视频
        boolean canPublishMedia = "publisher".equalsIgnoreCase(role);
        videoGrant.put("canPublish", canPublishMedia);

        // 2. 允许所有角色 (包括学生) 发布数据，以便他们能参与投票
        videoGrant.put("canPublishData", true);


        Map<String, Object> claims = new HashMap<>();
        claims.put("video", videoGrant);

        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        Date expiration = new Date(nowMillis + TOKEN_VALIDITY_SECONDS * 1000);

        return Jwts.builder()
                .setClaims(claims)
                .setIssuer(this.apiKey)
                .setSubject(user.getUsername())
                .setIssuedAt(now)
                .setNotBefore(now)
                .setExpiration(expiration)
                .signWith(this.apiSecret, SignatureAlgorithm.HS256)
                .compact();
    }
}
